package com.tul.vapp.servicecenter.service.impl;

import com.tul.cusa.zookeeper.IZookeeperClient;
import com.tul.vapp.servicecenter.bean.ServerStatus;
import com.tul.vapp.servicecenter.bean.ServerStatusVo;
import com.tul.vapp.servicecenter.bean.StatusItem;
import com.tul.vapp.servicecenter.common.CharSetConstant;
import com.tul.vapp.servicecenter.common.StatusEnum;
import com.tul.vapp.servicecenter.common.ZkNodeConstant;
import com.tul.vapp.servicecenter.dao.IReleaseAppDao;
import com.tul.vapp.servicecenter.dao.IReleaseItemDao;
import com.tul.vapp.servicecenter.dao.IReleaseNamespaceDao;
import com.tul.vapp.servicecenter.entity.App;
import com.tul.vapp.servicecenter.entity.Namespace;
import com.tul.vapp.servicecenter.service.IServerStatusService;
import com.tul.vapp.servicecenter.util.ItemIdUtil;
import com.tul.vapp.servicecenter.util.MessageUtil;
import com.tul.vapp.servicecenter.util.RegexUtil;
import com.tul.vapp.servicecenter.utils.ConfigUtil;
import com.tul.vapp.servicecenter.zookeeper.ZooKeeperClientFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * create by wujunlei
 *
 * @author wujunlei
 * @since 2018/1/5
 */
@Service
public class ServerStatusService implements IServerStatusService {

    /**
     * app dao
     */
    @Autowired
    private IReleaseAppDao appDao;

    /**
     * namespace dao
     */
    @Autowired
    private IReleaseNamespaceDao namespaceDao;
    @Autowired
    private IReleaseItemDao itemDao;

    /**
     * 查询服务状态
     *
     * @return List
     */
    @Override
    public List<ServerStatus> getServerStatus() {
        IZookeeperClient client = ZooKeeperClientFactory.getClient();
        List<String> nodeList = client.getChildren(ZkNodeConstant.STATUS_NODE);
        List<ServerStatus> serverList = new ArrayList<ServerStatus>();
        if (CollectionUtils.isEmpty(nodeList)) {
            return serverList;
        }
        for (String namespace : nodeList) {
            ServerStatus status = new ServerStatus();
            String appId = namespace.split("@")[0];
            String ip = namespace.split("@")[1];
            status.setIp(ip);
            status.setAppId(appId);
            if (RegexUtil.isEms(appId)) {
                //如果为ems代理，则appid为ems1...8，从namespace中获取相关信息。
                Namespace ems = namespaceDao.getNamespace("ems-proxy", appId);
                if (ems != null) {
                    status.setComment(ems.getComment());
                    status.setAppName(appId);
                }
            } else {
                App app = appDao.getApp(appId);
                if (app != null) {
                    status.setComment(app.getComment());
                    status.setAppName(app.getAppName());
                }
            }

            String nodePath = ZkNodeConstant.STATUS_NODE + ZkNodeConstant.SEPERATEOR + namespace;
            //获取节点数据
            byte[] data = client.getData(nodePath);
            Map<String, String> map = ConfigUtil.format(new String(data, CharSetConstant.UTF8));
            List<StatusItem> itemList = new ArrayList<StatusItem>();
            //插入或更新数据
            for (Map.Entry<String, String> entry : map.entrySet()) {
                StatusItem item = new StatusItem();
                item.setKey(entry.getKey());
                item.setValue(entry.getValue());
                String comment = StatusEnum.getDescBykey(entry.getKey());
                comment = MessageUtil.getMessage(comment);
                item.setComment(comment);
                itemList.add(item);
            }
            status.setItems(itemList);
            serverList.add(status);
        }
        return serverList;
    }

    /**
     * 获取服务总数
     *
     * @return List
     */
    @Override
    public List<ServerStatus> getStaticServerInfo() {
        List<ServerStatus> appStatuses = new ArrayList<ServerStatus>();
        List<App> appList = appDao.getApps();
        if (appList == null) {
            return appStatuses;
        }

        for (App app : appList) {
            String appId = app.getAppId();
            if ("ems-proxy".equals(appId)) {
                List<ServerStatus> emsStatus = getEmsStaticInfo();
                appStatuses.addAll(emsStatus);
                continue;
            }
            ServerStatus status = new ServerStatus();
            status.setAppName(app.getAppName());
            status.setAppId(appId);
            status.setComment(app.getComment());
            appStatuses.add(status);
        }
        return appStatuses;

    }

    @Override
    public List<ServerStatusVo> getServerStatusVo() {
        ItemIdUtil itemIdUtil = new ItemIdUtil();
        List<ServerStatus> activeStatusList = getServerStatus();
        Map<String, ServerStatus> activeStatusMap = new HashMap();
        //服务状态map
        Map<String, Boolean> appStatusMap = new HashMap();
        //服务ip map
        Map<String, String> appIpMap = new HashMap();
        for (ServerStatus status : activeStatusList) {
            activeStatusMap.put(status.getAppId(), status);
            appStatusMap.put(status.getAppId(), true);
            for (StatusItem item : status.getItems()) {
                if (item.getKey().equals("ip")) {
                    appIpMap.put(status.getAppId(), item.getValue());
                }
            }
        }
        List<ServerStatusVo> statusVos = new ArrayList();
        List<App> appList = appDao.getApps();
        if (appList == null) {
            return statusVos;
        }
        for (App app : appList) {
            String appId = app.getAppId();
            if ("global".equals(appId)) {
                continue;
            }
            if ("ems-proxy".equals(appId)) {
                List<ServerStatusVo> emsStatus = getEmsStaticVoInfo(itemIdUtil, activeStatusMap);
                statusVos.addAll(emsStatus);
                continue;
            }
            //父级对象
            ServerStatusVo statusVo = new ServerStatusVo();
            statusVo.setItemId(itemIdUtil.getParentId());
            statusVo.setKey(app.getAppName());
            statusVo.setValue(appIpMap.get(app.getAppId()));
            statusVo.setComment(app.getComment());
            if (null != appStatusMap.get(app.getAppId())) {
                statusVo.setStatus(true);
            } else {
                statusVo.setStatus(false);
            }
            statusVos.add(statusVo);
            ServerStatus appStatus = activeStatusMap.get(app.getAppId());
            if (appStatus != null) {
                for (StatusItem item : appStatus.getItems()) {
                    //子级对象
                    ServerStatusVo childStatusVo = new ServerStatusVo();
                    //设置父级id
                    childStatusVo.setParentId(statusVo.getItemId());
                    childStatusVo.setItemId(itemIdUtil.getChildId());
                    childStatusVo.setKey(item.getKey());
                    childStatusVo.setValue(item.getValue());
                    childStatusVo.setComment(MessageUtil.getMessage(item.getKey()));
                    statusVos.add(childStatusVo);
                }
            }
        }
        return statusVos;
    }

    /**
     * 特殊处理ems代理的服务状态
     *
     * @param itemIdUtil      id持有工具
     * @param activeStatusMap 状态map
     * @return 状态VO
     */
    private List<ServerStatusVo> getEmsStaticVoInfo(ItemIdUtil itemIdUtil, Map<String, ServerStatus> activeStatusMap) {

        List<Namespace> emsNamespaces = namespaceDao.getNamespaces("ems-proxy");
        Iterator iterator = emsNamespaces.iterator();
        while (iterator.hasNext()) {
            Namespace emsNs = (Namespace) iterator.next();
            if (!emsNs.getNamespace().contains("ems")) {
                iterator.remove();
            }
        }
        List<ServerStatusVo> serverStatusVos = new ArrayList();
        for (Namespace emsNamespace : emsNamespaces) {
            //ems父级对象
            ServerStatusVo serverStatusVo = new ServerStatusVo();
            serverStatusVo.setComment(emsNamespace.getComment());
            serverStatusVo.setItemId(itemIdUtil.getParentId());
            String emsName = emsNamespace.getNamespace().replace(".properties", "");
            serverStatusVo.setKey(emsName);
            //先设置状态为false
            serverStatusVo.setStatus(false);
            //如果从zk上同步的活跃app中包含此ems且sync=success，则状态改为true,同时获取端口号
            checkZk(emsNamespace, serverStatusVo);
            //将父级加入返回对象中
            serverStatusVos.add(serverStatusVo);
            ServerStatus status = activeStatusMap.get(emsName);
            if (status != null) {
                for (StatusItem item : status.getItems()) {
                    if ("ip".equals(item.getKey())) {
                        serverStatusVo.setValue(item.getValue());
                    }
                    //子级对象
                    ServerStatusVo childStatusVo = new ServerStatusVo();
                    //设置父级id
                    childStatusVo.setParentId(serverStatusVo.getItemId());
                    childStatusVo.setItemId(itemIdUtil.getChildId());
                    childStatusVo.setKey(item.getKey());
                    childStatusVo.setValue(item.getValue());
                    childStatusVo.setComment(MessageUtil.getMessage(item.getKey()));
                    serverStatusVos.add(childStatusVo);
                }
            }

        }
        return serverStatusVos;
    }

    /**
     * 检测zk
     *
     * @param emsNamespace   ems命名空间
     * @param serverStatusVo 服务状态VO
     */
    private void checkZk(Namespace emsNamespace, ServerStatusVo serverStatusVo) {
        List<ServerStatus> activeServerStatusList = getServerStatus();
        for (ServerStatus serverStatus : activeServerStatusList) {
            if (serverStatus.getAppId().equals(emsNamespace.getNamespace().replace(".properties", ""))) {
                List<StatusItem> items = serverStatus.getItems();
                for (StatusItem item : items) {
                    if (item.getKey().equals("sync")) {
                        if (item.getValue().equals("success")) {
                            serverStatusVo.setStatus(true);
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取ems应用信息
     *
     * @return List
     */
    private List<ServerStatus> getEmsStaticInfo() {
        List<Namespace> emsNamespace = namespaceDao.getNamespaces("ems-proxy");
        List<ServerStatus> emsStatus = new ArrayList<ServerStatus>();
        if (emsNamespace == null) {
            return emsStatus;
        }
        for (Namespace namespace : emsNamespace) {
            String namespanceId = namespace.getNamespace();
            if (RegexUtil.isEms(namespanceId)) {
                ServerStatus status = new ServerStatus();
                if (namespanceId.endsWith(".properties")) {
                    namespanceId = namespanceId.replace(".properties", "");
                }
                status.setAppId(namespanceId);
                status.setComment(namespace.getComment());
                status.setAppName(namespace.getComment());
                emsStatus.add(status);
            }
        }
        return emsStatus;
    }
}
